{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "96874d5f",
   "metadata": {},
   "source": [
    "# 卷积层\n",
    "\n",
    "视频：https://www.bilibili.com/video/BV1L64y1m7Nh?p=3\n",
    "\n",
    "6.1 6.2章：https://zh-v2.d2l.ai/chapter_convolutional-neural-networks/conv-layer.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6e4fd8ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "from d2l import torch as d2l\n"
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "id": "87a509dd",
   "metadata": {},
   "source": [
    "## 1.互相关运算\n",
    "![image.png](attachment:image.png)\n",
    "\n",
    "卷积后图像大小（默认步长）：（原图像长 - 卷积核长 + 1） * （原图像宽 - 卷积核宽 + 1）\n",
    "\n",
    "卷积后图像大小：（（原图像长 - 卷积核长 + 填充 + 横向步幅）/横向步幅） * （（原图像宽 - 卷积核宽 + 填充 + 纵向步幅）/纵向步幅）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "844da2d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "* 2D卷积计算\n",
    "* args：\n",
    "    @param X：目标矩阵tensor\n",
    "    @param K：卷积核矩阵tensor\n",
    "    \n",
    "* return：\n",
    "    @return Y：卷积计算后的结果矩阵 \n",
    "\n",
    "\"\"\"\n",
    "\n",
    "def corr2d(X, K):  \n",
    "    h, w = K.shape  # h卷积核长 w卷积核宽\n",
    "    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1)) #卷积后的结果矩阵大小：（原图像长 - 卷积核长 + 1）*（原图像宽 - 卷积核宽 + 1）\n",
    "    \n",
    "    for i in range(Y.shape[0]):\n",
    "        for j in range(Y.shape[1]):\n",
    "            Y[i, j] = (X[i:i + h, j:j + w] * K).sum()\n",
    "            \n",
    "    return Y\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "413736ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[19., 25.],\n",
       "        [37., 43.]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])\n",
    "K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])\n",
    "corr2d(X, K)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bbad7060",
   "metadata": {},
   "source": [
    "## 2.卷积层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab0ed912",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Conv2D(nn.Module):\n",
    "    \n",
    "    # 在 __init__ 构造函数中，将 weight 和 bias 声明为两个模型参数\n",
    "    def __init__(self, kernel_size):\n",
    "        super().__init__()\n",
    "        self.weight = nn.Parameter(torch.rand(kernel_size))\n",
    "        self.bias = nn.Parameter(torch.zeros(1))\n",
    "\n",
    "    # 前向传播函数调用 corr2d 函数并添加偏置\n",
    "    def forward(self, x):\n",
    "        return corr2d(x, self.weight) + self.bias"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60d2b1fc",
   "metadata": {},
   "source": [
    "## 3.图像中目标的边缘检测 \n",
    "\n",
    "卷积层应用：通过找到像素变化的位置，来检测图像中不同颜色的边缘"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "04abbd0e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1., 0., 0., 0., 0., 1., 1.],\n",
       "        [1., 1., 0., 0., 0., 0., 1., 1.],\n",
       "        [1., 1., 0., 0., 0., 0., 1., 1.],\n",
       "        [1., 1., 0., 0., 0., 0., 1., 1.],\n",
       "        [1., 1., 0., 0., 0., 0., 1., 1.],\n",
       "        [1., 1., 0., 0., 0., 0., 1., 1.]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 目标待检测的矩阵\n",
    "X = torch.ones((6, 8))\n",
    "X[:, 2:6] = 0\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d5eaeb08",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 卷积核矩阵\n",
    "K = torch.tensor([[1.0, -1.0]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5f878262",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
       "        [ 0.,  1.,  0.,  0.,  0., -1.,  0.]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 检测结果，边缘为1和-1\n",
    "Y = corr2d(X, K)\n",
    "Y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f986a8d",
   "metadata": {},
   "source": [
    "## 3.学习卷积核\n",
    "通过仅查看“输入-输出”对来学习由 X 生成 Y 的卷积核"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "aa8d1474",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造一个二维卷积层，它具有1个输出通道和形状为（1，2）的卷积核\n",
    "\n",
    "# nn.Conv2d(in_channels=输入图片通道数,out_channels=输出的张量通道数, kernel_size=(卷积核高, 卷积核宽), bias=偏置T/F)\n",
    "\n",
    "conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "01d37c28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X tensor([[[[1., 1., 0., 0., 0., 0., 1., 1.],\n",
      "          [1., 1., 0., 0., 0., 0., 1., 1.],\n",
      "          [1., 1., 0., 0., 0., 0., 1., 1.],\n",
      "          [1., 1., 0., 0., 0., 0., 1., 1.],\n",
      "          [1., 1., 0., 0., 0., 0., 1., 1.],\n",
      "          [1., 1., 0., 0., 0., 0., 1., 1.]]]])\n",
      "Y tensor([[[[ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
      "          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
      "          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
      "          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
      "          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],\n",
      "          [ 0.,  1.,  0.,  0.,  0., -1.,  0.]]]])\n"
     ]
    }
   ],
   "source": [
    "# 这个二维卷积层使用四维输入和输出格式（图片数量N、通道C、高度H、宽度W），\n",
    "# 其中批量大小和通道数都为1\n",
    "\n",
    "X = X.reshape((1, 1, 6, 8))  # 输入\n",
    "Y = Y.reshape((1, 1, 6, 7))  # 输出\n",
    "\n",
    "print('X',X)\n",
    "print('Y',Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "ceedc4be",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "batch 2, loss 3.539\n",
      "batch 4, loss 0.595\n",
      "batch 6, loss 0.100\n",
      "batch 8, loss 0.017\n",
      "batch 10, loss 0.003\n"
     ]
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    Y_hat = conv2d(X)            # Y_hat 预测结果\n",
    "    l = (Y_hat - Y) ** 2        # 损失函数（平方损失）\n",
    "    \n",
    "    conv2d.zero_grad()          # 梯度清理\n",
    "    l.sum().backward()           # 反向传递 损失累加\n",
    "    \n",
    "    # 迭代卷积核\n",
    "    conv2d.weight.data[:] -= 3e-2 * conv2d.weight.grad   # 权重更新(学习率3e-2，梯度conv2d.weight.grad)\n",
    "    \n",
    "    # 轮数是偶数时输出累计损失\n",
    "    if (i + 1) % 2 == 0:\n",
    "        print(f'batch {i+1}, loss {l.sum():.3f}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "131322de",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.9892, -0.9913]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 学习得到的卷积核\n",
    "\n",
    "conv2d.weight.data.reshape((1, 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ea8fb01",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
